package cate.game.server.schedule;

import cate.game.GameBody;
import cate.game.ManyGame;
import cate.game.framework.ReportHandler;
import cate.game.framework.ThreadShare;
import cate.game.framework.share.Shared;
import cate.game.server.service.MailService;
import cp.game.framework.ApiCaller;
import easy.java.practice.errorcode.EcException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;

@Slf4j
@Configuration
@EnableScheduling
public class EveryNSecond {

    private final ManyGame games;

    public EveryNSecond(ManyGame games) {
        this.games = games;
    }

    @Resource
    MailService mailService;
    @Autowired
    ApiCaller apiCaller;

    @Scheduled(fixedDelay = 1000, initialDelay = 3000)
    public void t1() {
        this.games.scheduleExecute(game -> () -> {
            try{
                long start = System.currentTimeMillis();
                game.tick();
                long cost = System.currentTimeMillis() - start;
                if(cost > 1000){
                    log.info("game{} tick cost={} ms", game.config.srvId, cost);
                }
            }catch(Exception e){
                log.error("game{} t1定时任务异常", game.config.srvId, e);
            }
        });
    }

    @Scheduled(fixedDelay = 5000, initialDelay = 2000)
    public void t2() {
        this.games.checkShutdown();
        this.games.scheduleExecute(game -> () -> {
            try{

                game.facilities.getMongoCache().flushFew();

                long start = System.currentTimeMillis();
                int index = game.role.checkActive();
                long cost = System.currentTimeMillis() - start;
                if(cost > 2000 || index > 100){
                    log.info("game{} checkactive 共{}次保存 cost={} ms", game.config.srvId, index, cost);
                }
                game.res.guild.getGuildList().forEach(guild -> guild.envelope.checkExpire());
            }catch(Exception e){
                log.error("game{} t2定时任务异常", game.config.srvId, e);
            }
        });
    }

    @Scheduled(fixedDelay = 30000, initialDelay = 5000)
    public void t3() {
        for(GameBody game : this.games.getAllIncludeNotOpen()) {
            game.config.reloadOptionally(game.facilities);
        }
        mailService.update();
        ThreadShare.logStatus();
    }

    @Scheduled(fixedDelay = 12000, initialDelay = 4000)
    public void everyDozenSeconds() {
        ReportHandler.sendReport(this.apiCaller, this.games);
        try {
            Shared.logic.everyDozenSeconds();
        } catch (EcException e) {
            log.error("游戏共享逻辑异常everyDozenSeconds code={}, message={}", e.code, e.message, e);
        } catch (Exception e) {
            log.error("游戏共享逻辑异常everyDozenSeconds", e);
        }
    }

    @Scheduled(fixedDelay = 180000, initialDelay = 60000)
    public void every3min() {
        this.games.scheduleExecute(game -> () -> {
            try {
                game.every3Min();
            } catch (Exception e) {
                log.error("game(id={})发生错误", game.config.srvId, e);
            }
        });
    }

    @Scheduled(fixedDelay = 600000, initialDelay = 60000)
    public void scheduleSystemNotice() {
        this.games.scheduleExecute(game -> () -> {
            try{
//                TextLampRow row = game.table.text.lamp.randomSystemNotice();
//                ChatFacade.sendSystemAsSystem(game, row.id, new ArrayList<>());
                game.res.guild.getGuildList().forEach(guild -> guild.member.synSnapShot(game));
            }catch(Exception e){
                log.error("game{} scheduleSystemNotice定时任务异常", game.config.srvId, e);
            }
        });
    }

    @Scheduled(cron = "1 0 0 * * ?")
    public void onDaySpan() {
        log.info("执行跨天事件");
        this.games.scheduleExecute(game -> () -> {
            try{
                game.onDaySpan();
            }catch(Exception e){
                log.error("game{} onDaySpan定时任务异常", game.config.srvId, e);
            }
        });
    }

    @Scheduled(cron = "1 0 0 ? * MON")
    public void onWeekSpan() {
        log.info("执行跨周事件");
        this.games.scheduleExecute(game -> () -> {
            try{
                game.onWeekSpan();
            }catch (Exception e){
                log.error("game{} onWeekSpan定时任务异常", game.config.srvId, e);
            }
        });
    }

    @Scheduled(cron = "1 0 0 1 * ?")
    public void onMonthSpan() {
        log.info("执行跨月事件");
        this.games.scheduleExecute(game -> () -> {
            try{
                game.onMonthSpan();
            }catch (Exception e){
                log.error("game{} onMonthSpan定时任务异常", game.config.srvId, e);
            }
        });
    }

    @Scheduled(cron = "1 0 0/1 * * ?")
    public void onHourSpan() {
        this.games.scheduleExecute(game -> () -> {
            try {
                game.onHourSpan();
            } catch (Exception e) {
                log.error("game{} onHourSpan定时任务异常", game.config.srvId, e);
            }
        });
    }
}
